All the features from markdown and markdown supported within .Rmd documents, I was able to get from within R scripts. Here are some that I tested and use most frequently:
#' instead of just ##' # for h1, #' ## for h2, etc.toc: true to YAML frontmatter to create a table of contents with links like the one at the top of this page that links to h1, h2 & h3’s indented like so:
#' * with 4 spaces per level of indentation.* to italicize** to bold*** to italicize & bold#' <br>#' <!-- this text will not print in report --># comments without the extra tick show up like this. And get included in code blocks
# loading mtcars data
data(mtcars)
pdf.tbl<-dplyr::mutate_if(pdf.tbl, is.numeric, format_dol_fun)
pdf.tbl[is.na(pdf.tbl)] <- ""
data(pdf.tbl)## Warning in data(pdf.tbl): data set 'pdf.tbl' not found
library('knitr')mtcars[1:5, 1:4] %>%
mutate(
car = row.names(.),
mpg = color_tile("white", "orange")(mpg),
cyl = cell_spec(cyl, "html", angle = (1:5)*60,
background = "red", color = "white", align = "center"),
disp = ifelse(disp > 200,
cell_spec(disp, "html", color = "red", bold = T),
cell_spec(disp, "html", color = "green", italic = T)),
hp = color_bar("lightgreen")(hp)
) %>%
select(car, everything()) %>%
kable("html", escape = F) %>%
kable_styling("hover", full_width = F) %>%
column_spec(5, width = "3cm") %>%
add_header_above(c(" ", "Hello" = 2, "World" = 2))| car | mpg | cyl | disp | hp |
|---|---|---|---|---|
| Mazda RX4 | 21.0 | 6 | 160 | 110 |
| Mazda RX4 Wag | 21.0 | 6 | 160 | 110 |
| Datsun 710 | 22.8 | 4 | 108 | 93 |
| Hornet 4 Drive | 21.4 | 6 | 258 | 110 |
| Hornet Sportabout | 18.7 | 8 | 360 | 175 |
…specifically a data.frame in this case. Ordered from least to most pretty (in my opinion).
print(head(pdf.tbl))## Description 2007-08 2008-09 2009-10 2010-11 2011-12 2012-13
## 1 Resident Costs*:
## 2 Tuition & Fees $5,622 $6,030 $7,530 $8,736 $9,472 $9,842
## 3 Books & Supplies $840 $900 $960 $1,030 $1,078 $848
## 4 Room & Board $7,292 $7,528 $8,046 $8,460 $8,708 $8,970
## 5 Misc. & Travel $2,300 $2,300 $1,464 $1,510 $1,562 $1,590
## 6 Resident Total Costs $16,054 $16,758 $18,000 $19,736 $20,820 $21,250
## 2013-14 2014-15 2015-16 2016-17
## 1
## 2 $10,262 $10,836 $11,622 $11,634
## 3 $916 $800 $840 $1,006
## 4 $9,246 $9,246 $9,450 $9,616
## 5 $1,640 $1,798 $3,222 $3,952
## 6 $22,064 $22,680 $25,134 $26,208
print(head(mtcars))## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
knitr::kable(head(pdf.tbl))| Description | 2007-08 | 2008-09 | 2009-10 | 2010-11 | 2011-12 | 2012-13 | 2013-14 | 2014-15 | 2015-16 | 2016-17 |
|---|---|---|---|---|---|---|---|---|---|---|
| Resident Costs*: | ||||||||||
| Tuition & Fees | $5,622 | $6,030 | $7,530 | $8,736 | $9,472 | $9,842 | $10,262 | $10,836 | $11,622 | $11,634 |
| Books & Supplies | $840 | $900 | $960 | $1,030 | $1,078 | $848 | $916 | $800 | $840 | $1,006 |
| Room & Board | $7,292 | $7,528 | $8,046 | $8,460 | $8,708 | $8,970 | $9,246 | $9,246 | $9,450 | $9,616 |
| Misc. & Travel | $2,300 | $2,300 | $1,464 | $1,510 | $1,562 | $1,590 | $1,640 | $1,798 | $3,222 | $3,952 |
| Resident Total Costs | $16,054 | $16,758 | $18,000 | $19,736 | $20,820 | $21,250 | $22,064 | $22,680 | $25,134 | $26,208 |
knitr::kable(head(mtcars))| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Mazda RX4 | 21.0 | 6 | 160 | 110 | 3.90 | 2.620 | 16.46 | 0 | 1 | 4 | 4 |
| Mazda RX4 Wag | 21.0 | 6 | 160 | 110 | 3.90 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
| Datsun 710 | 22.8 | 4 | 108 | 93 | 3.85 | 2.320 | 18.61 | 1 | 1 | 4 | 1 |
| Hornet 4 Drive | 21.4 | 6 | 258 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
| Hornet Sportabout | 18.7 | 8 | 360 | 175 | 3.15 | 3.440 | 17.02 | 0 | 0 | 3 | 2 |
| Valiant | 18.1 | 6 | 225 | 105 | 2.76 | 3.460 | 20.22 | 1 | 0 | 3 | 1 |
including #+ results='asis' chunk option for formatting
knitr::kable(pdf.tbl)| Description | 2007-08 | 2008-09 | 2009-10 | 2010-11 | 2011-12 | 2012-13 | 2013-14 | 2014-15 | 2015-16 | 2016-17 |
|---|---|---|---|---|---|---|---|---|---|---|
| Resident Costs*: | ||||||||||
| Tuition & Fees | $5,622 | $6,030 | $7,530 | $8,736 | $9,472 | $9,842 | $10,262 | $10,836 | $11,622 | $11,634 |
| Books & Supplies | $840 | $900 | $960 | $1,030 | $1,078 | $848 | $916 | $800 | $840 | $1,006 |
| Room & Board | $7,292 | $7,528 | $8,046 | $8,460 | $8,708 | $8,970 | $9,246 | $9,246 | $9,450 | $9,616 |
| Misc. & Travel | $2,300 | $2,300 | $1,464 | $1,510 | $1,562 | $1,590 | $1,640 | $1,798 | $3,222 | $3,952 |
| Resident Total Costs | $16,054 | $16,758 | $18,000 | $19,736 | $20,820 | $21,250 | $22,064 | $22,680 | $25,134 | $26,208 |
| Nonresident Costs*: | ||||||||||
| Tuition & Fees | $20,726 | $22,342 | $25,740 | $26,946 | $27,682 | $28,052 | $28,472 | $29,046 | $29,832 | $29,844 |
| Books & Supplies | $840 | $900 | $960 | $1,030 | $1,078 | $848 | $916 | $800 | $840 | $1,006 |
| Room & Board | $7,292 | $7,528 | $8,046 | $8,460 | $8,708 | $8,970 | $9,246 | $9,246 | $9,450 | $9,616 |
| Misc. & Travel | $2,300 | $2,300 | $1,464 | $1,510 | $1,562 | $1,590 | $1,640 | $1,798 | $3,746 | $4,662 |
| Nonresident Total Costs | $31,158 | $33,070 | $36,210 | $37,946 | $39,030 | $39,460 | $40,274 | $40,890 | $43,868 | $45,128 |
knitr::kable(head(mtcars))| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Mazda RX4 | 21.0 | 6 | 160 | 110 | 3.90 | 2.620 | 16.46 | 0 | 1 | 4 | 4 |
| Mazda RX4 Wag | 21.0 | 6 | 160 | 110 | 3.90 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
| Datsun 710 | 22.8 | 4 | 108 | 93 | 3.85 | 2.320 | 18.61 | 1 | 1 | 4 | 1 |
| Hornet 4 Drive | 21.4 | 6 | 258 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
| Hornet Sportabout | 18.7 | 8 | 360 | 175 | 3.15 | 3.440 | 17.02 | 0 | 0 | 3 | 2 |
| Valiant | 18.1 | 6 | 225 | 105 | 2.76 | 3.460 | 20.22 | 1 | 0 | 3 | 1 |
plot(mtcars$mpg, mtcars$disp, col=mtcars$cyl, pch=19)We can change the chunk options we would use for a code block using knitr by using a comment that starts with #+. For example, to change the plot size, we can specify #+ fig.width=4, fig.height=4 before plotting.
A new chunk is automatically generated (chunk settings reset) whenever we add document text with #' or change. However, it is possible to specify global chunk options, if desired. chunk options again with #+.
#+ fig.width=4, fig.height=4
plot(mtcars\(mpg, mtcars\)disp, col=mtcars$cyl, pch=19) Small plots often render with strange resolution and relative sizings of labels, axes, etc. The dpi chunk option can be used to fix this. Just be sure to adjust the fig.width and fig.height accordingly.
Bad plot: #+ fig.width=2, fig.height=2
hist(mtcars$mpg)Good plot: #+ fig.width=4, fig.height=4, dpi=50
hist(mtcars$mpg)Generate a series of plots from a loop
for(i in 1:ncol(mtcars)) hist(mtcars[,i], breaks=40, xlab='', main=names(mtcars)[i])… and explore some model output. First here’s a big chunk of text from the random forest documentation:
Random forest documentation:
randomForest implements Breiman’s random forest algorithm (based on Breiman and Cutler’s original Fortran code) for classification and regression. It can also be used in unsupervised mode for assessing proximities among data points.
Note:
The forest structure is slightly different between classification and regression. For details on how the trees are stored, see the help page for getTree.
If xtest is given, prediction of the test set is done “in place†as the trees are grown. If ytest is also given, and do.trace is set to some positive integer, then for every do.trace trees, the test set error is printed. Results for the test set is returned in the test component of the resulting randomForest object. For classification, the votes component (for training or test set data) contain the votes the cases received for the classes. If norm.votes=TRUE, the fraction is given, which can be taken as predicted probabilities for the classes.
For large data sets, especially those with large number of variables, calling randomForest via the formula interface is not advised: There may be too much overhead in handling the formula.
The “local†(or casewise) variable importance is computed as follows: For classification, it is the increase in percent of times a case is OOB and misclassified when the variable is permuted. For regression, it is the average increase in squared OOB residuals when the variable is permuted.
# OK. now let's actually use random.forest
library('randomForest')
mtcars$am <- as.factor(mtcars$am)
rf <- randomForest(am~., ntree=100, data=mtcars)Here’s the resulting confusion matrix on the training data. Not very clear to a non-technical or non-forest savvy audience.
print(rf)##
## Call:
## randomForest(formula = am ~ ., data = mtcars, ntree = 100)
## Type of random forest: classification
## Number of trees: 100
## No. of variables tried at each split: 3
##
## OOB estimate of error rate: 12.5%
## Confusion matrix:
## 0 1 class.error
## 0 17 2 0.1052632
## 1 2 11 0.1538462
We can get fancy and actually dynamically generate some commentary around these results. That is we can auto-fill parts of our document text with objects from the R environment. This could be useful with analyses that involve stochastic elements changing from run to run like random forest. Or any analysis where results are subject to change.
17 cars are correctly classified as 0.
11 cars are correctly classified as 1.
2 cars are misclassified as 1.
2 cars are misclassified as 0.
These numbers were generated by wrapping the R expression to excute into the ticks like so: I don’t know how to write this within a #' comment without evaluating it, so I’m documenting here as a character string:
## #' `r rf$confusion[2,1]` cars are misclassified as 0.
This is useful if you want to generate lots of text without writing it manually.
#+ results='asis'
for (i in 1:10) {
rf <- randomForest(am~., ntree=100, data=mtcars)
cat("iteration ",i, ": ", rf$confusion[1,1], "cars are correctly classified as 0", "\n")
cat('\n')
}iteration 1 : 16 cars are correctly classified as 0
iteration 2 : 17 cars are correctly classified as 0
iteration 3 : 17 cars are correctly classified as 0
iteration 4 : 18 cars are correctly classified as 0
iteration 5 : 17 cars are correctly classified as 0
iteration 6 : 17 cars are correctly classified as 0
iteration 7 : 17 cars are correctly classified as 0
iteration 8 : 16 cars are correctly classified as 0
iteration 9 : 17 cars are correctly classified as 0
iteration 10 : 17 cars are correctly classified as 0
Much like we used R objects to dynamically generate text to print in the document (in the form of comments), we can use R objects to dynamically specify chunk options.
When we set evaluateStuff to TRUE or FALSE, the following 3 chunks will evaluate (or not) as we choose. We can toggle them all with one variable, instead of manually changing the chunk settings with #+ eval=T in the R script multiple times. Simply include the variable you want to execute in the chunk comments with ticks.
Like so: #+ eval=`evaluateStuff`
evaluateStuff <- Tcat('first thing to evaluate')## first thing to evaluate
cat('second thing to evaluate')## second thing to evaluate
cat('third thing to evaluate')## third thing to evaluate
Now let’s just print the code and not evaluate anything.
evaluateStuff <- Fcat('first thing to evaluate')cat('second thing to evaluate')cat('third thing to evaluate')If you did everyhing right, above this is the easy part. Simply render the script as desired with the render function from rmarkdown.
rmarkdown::render('/Users/you/Documents/yourscript.R')